﻿using Dotnet.Utils.Utility.StreamUtil;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dotnet.Utils.Utility.Other
{
    public class GCHelper
    {
        /// <summary>
        /// 强制对所有代进行即时垃圾回收
        /// </summary>
        public static void Collect()
        {
            GC.Collect(); // 触发 GC
            GC.WaitForPendingFinalizers(); // 等待终结器完成
            GC.Collect(); // 回收已终结的对象
        }

        /// <summary>
        /// 判断是否是服务器GC模式
        /// </summary>
        /// <returns></returns>
        public static bool IsServerGC()
        {
            return System.Runtime.GCSettings.IsServerGC;
        }

        /// <summary>
        /// 获取System.GC工作方式
        /// </summary>
        /// <returns></returns>
        public static bool Concurrent()
        {
            return GC.GetGCMemoryInfo().Concurrent;
        }

        /// <summary>
        /// 获取LatencyMode
        /// Batch 表示非并发GC，Interactive 表示并发GC
        /// </summary>
        /// <returns></returns>
        public static string LatencyMode()
        {
            return System.Runtime.GCSettings.LatencyMode.ToString();
        }

        /// <summary>
        /// 获取程序运行总内存
        /// </summary>
        /// <returns></returns>
        public static string GetTotalMemory()
        {
            // 获取当前进程
            Process currentProcess = Process.GetCurrentProcess();

            // 获取私有内存大小（单位：字节）
            long privateMemory = currentProcess.PrivateMemorySize64;

            // 获取工作集内存大小（单位：字节）
            long workingSetMemory = currentProcess.WorkingSet64;

            // 获取托管内存大小（单位：字节）
            long totalMemory = GC.GetTotalMemory(false);

            //总可用内存
            long totalBytes = GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.AppendFormat("GC内存大小:{0}\r\n", FileHelper.FormatBytes(totalMemory));
            stringBuilder.AppendFormat("私有内存大小:{0}\r\n", FileHelper.FormatBytes(privateMemory));
            stringBuilder.AppendFormat("工作集内存大小:{0}\r\n", FileHelper.FormatBytes(workingSetMemory));
            stringBuilder.AppendFormat("总可用内存:{0}\r\n", FileHelper.FormatBytes(totalBytes));
            string str = stringBuilder.ToString();
            return str;
        }

        /// <summary>
        /// 获取上次垃圾回收发生时垃圾回收器使用的总可用内存
        /// </summary>
        /// <returns></returns>
        public static string TotalAvailableMemory()
        {
            long totalBytes = GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;
            decimal gb = (decimal)totalBytes / 1024 / 1024 / 1024;
            return gb.ToString("f2") + "GB";
        }
    }
}
